package cs2340.spring13.team3.wheresmystuff.views;

import java.io.IOException;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.codehaus.jackson.JsonParseException;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import cs2340.spring13.team3.wheresmystuff.R;
import cs2340.spring13.team3.wheresmystuff.model.Item;
import cs2340.spring13.team3.wheresmystuff.model.ServerObject;
import cs2340.spring13.team3.wheresmystuff.model.ServerObject.SyncException;
import cs2340.spring13.team3.wheresmystuff.model.User;
import cs2340.spring13.team3.wheresmystuff.presenters.LoginManager;

/**
 * Allows the user to match an item they find with one of their own items
 * 
 * @author Ryan Keane
 * @version 0.1
 * 
 */
public class MatchItemActivity extends Activity {
	public static final long MAP_PASSING_INDEX = 0L;

	private User currentUser;
	private List<Item> itemNames;
	private Item matchingItem;
	private MatchItemTask mMatchTask;

	@SuppressLint("SimpleDateFormat")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_match_item);
		Spinner lv = (Spinner) findViewById(R.id.matcherDropDown);

		Serializable m = getIntent().getSerializableExtra("map");
		if (m == null || !(m instanceof HashMap)) {
			throw new NullPointerException(
					"Error: Item Map passed incorrectly to matcher.");
		}

		@SuppressWarnings("unchecked")
		HashMap<Long, Item> map = (HashMap<Long, Item>) m;
		Item i = map.get(MAP_PASSING_INDEX);
		if (i == null) {
			throw new NullPointerException(
					"Error: Item passed incorrectly to matcher.");
		}
		matchingItem = i;

		TextView itemName = (TextView) this.findViewById(R.id.matchItemName);
		itemName.setText(i.getName());
		TextView itemDate = (TextView) this.findViewById(R.id.matchItemDate);
		itemDate.setText(new SimpleDateFormat("yyyy-MM-dd").format(i.getDate()));
		TextView itemStub = (TextView) this.findViewById(R.id.matchItemStub);
		itemStub.setText(i.getDescription());

		currentUser = LoginManager.getInstance().getUser();
		List<Item> lostItems = currentUser.getItems();
		itemNames = new ArrayList<Item>();

		for (Item item : lostItems) {
			if (item.getFound().compareTo(i.getFound()) != 0) {
				itemNames.add(item);
			}
		}

		ArrayAdapter<Item> adapter = new ArrayAdapter<Item>(this,
				android.R.layout.simple_spinner_item, itemNames);
		lv.setAdapter(adapter);
		lv.setSelection(0);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_match_item, menu);
		return true;
	}

	/**
	 * cancel's this screen and goes back to the last one.
	 * 
	 * @param view
	 */
	public void onCancelClick(View view) {
		returnToLast(ViewItemListActivity.MERGE_FAILURE);
	}

	/**
	 * Starts the addItemActivity when the user clicks the "add more" button.
	 * 
	 * @param view
	 */
	public void onMatchClick(View view) {
		Spinner lv = (Spinner) findViewById(R.id.matcherDropDown);
		Item item = (Item) lv.getSelectedItem();
		if (item == null) {
			AlertDialog alertDialog = new AlertDialog.Builder(this).create();
			alertDialog.setTitle("Error");
			alertDialog
					.setMessage("Please select your item to match with this one");
			alertDialog.show();
		} else {
			if (mMatchTask == null) {
				mMatchTask = new MatchItemTask(this, matchingItem, item);
				mMatchTask.execute((Void) null);
			}
		}
	}

	/**
	 * Method run to return to the calling method
	 */
	private void returnToLast(int key) {
		Intent i = new Intent();
		setResult(key, i);
		finish();
	}

	/**
	 * Represents an asynchronous login/registration task used to authenticate
	 * the user.
	 */
	public class MatchItemTask extends AsyncTask<Void, Void, Boolean> {
		private Activity activity;
		private Item a;
		private Item b;
		private Exception err;

		/**
		 * Create the item and sync it to the backend in the background
		 * 
		 * @param applicationActivity
		 * @param itemName
		 * @param itemDescription
		 * @param itemReward
		 * @param isLost
		 * @param itemTagList
		 */
		public MatchItemTask(Activity applicationActivity, Item a, Item b) {
			this.activity = applicationActivity;
			this.a = a;
			this.b = b;
		}

		@Override
		protected Boolean doInBackground(Void... params) {
			try {
				// this.newItem = new Item(name, description, reward, lost,
				// tags, date);
				a.setMatchName(b.getName());
				b.setMatchName(a.getName());
				String aJson = ServerObject.getObjectMapper()
						.writeValueAsString(a.toJson());
				String bJson = ServerObject.getObjectMapper()
						.writeValueAsString(b.toJson());
				a.update(aJson);
				b.update(bJson);
				return true;
			} catch (JsonParseException e) {
				this.err = e;
			} catch (IOException e) {
				this.err = e;
			} catch (SyncException e) {
				e.printStackTrace();
			}
			return false;
		}

		@Override
		protected void onPostExecute(final Boolean success) {
			mMatchTask = null;
			if (success) {
				try {
					returnToLast(ViewItemListActivity.MERGE_SUCCESS);
				} catch (Exception e) {
					e.printStackTrace();
				}

			} else {
				if (this.err != null) {
					AlertDialog alertDialog = new AlertDialog.Builder(
							this.activity).create();
					alertDialog.setTitle("Error!");
					alertDialog.setMessage(this.err.getMessage());
					alertDialog.show();
					this.err.printStackTrace();
				}
			}
		}

		@Override
		protected void onCancelled() {
			mMatchTask = null;
		}
	}

}
